addHook("PlayerThink", function(p) //hack fix, replace this later
	if p.shouldkill == 1 and p.playerstate == PST_LIVE then
		P_DamageMobj(p.mo, 0, 0, 0, DMG_INSTAKILL)
		//print(p.name .. " IS A STUPID FUCKING IDIOT CUCK")
	end
	if p.phealth ~= nil and p.phealth <= 0 and p.playerstate == PST_LIVE then
		p.shouldkill = 1
	else
		p.shouldkill = 0
	end
end)

addHook("PlayerThink", function(p)
	if p.phealth == nil then //if our health is nil
		p.phealth = RFW.MHealth //make sure its not lol
	end //as an added benefit we can set phealth to nil in order to reset it to default as a shortcut
	if p.parmor == nil then //same with armor
		p.parmor = 0 //don't start with armor, you can change this if needed
	end
	if p.parmor > RFW.MArmor then
		p.parmor = RFW.MArmor
	end
	if p.papval == nil then
		p.papval = 0
	end
	if p.parmor <= 0 and p.papval > 0 then
		p.papval = 0
	end
	if p.parmor > 0 and p.papval <= 0 then
		p.papval = 33 //set this to whatever you want the default protection value to be for items that don't set it
	end
	if RFW.OHealth and p.phealth > RFW.OHealth then
		p.phealth = RFW.OHealth
	end
	p.powers[pw_shield] = 0
	if p.playerstate == PST_DEAD then
		if p.phealth > 0 then
			p.phealth = 0
		end
		if p.parmor > 0 then
			p.parmor = 0
		end
	end
end)

COM_AddCommand("dev_healthdebug", function (p, a, b, c)
	p.phealth = tonumber(a)
	p.parmor = tonumber(b)
	p.papval = tonumber(c)
end, COM_ADMIN)

COM_AddCommand("dev_healthdebug2", function (p, a, b, c)
	p.phealth = tonumber(a)
	p.parmor = tonumber(b)
	p.papval = tonumber(c)
end, COM_SPLITSCREEN)

addHook("PlayerSpawn", function(p)
	if p.phealth == nil then //dumb fucking error...
		p.phealth = RFW.MHealth 
	end 
	if p.parmor == nil then 
		p.parmor = 0 
	end
	if p.papval == nil then
		p.papval = 0
	end
	
	if p.phealth <= 0 then //check if we're a zombie
		p.phealth = RFW.MHealth //reset our health
		p.parmor = 0 //we shouldn't keep our armor from last life
		p.papval = 0
	end
end)

rawset(_G, "Playerdamage", function(t, i, s, d, dt, override, nkb) //damage function, target inflictor source damage damagetype
	if dt and dt & DMG_DEATHMASK then
		P_DamageMobj(t, i, s, d, dt)
		return true
	end //end if DMG_DEATHMASK flag (instakill flag)
	if t.player.spectator then return true end
	if t.godpowerup ~= nil and t.godpowerup > 0 and not (RFW.ACIDTABLE[dt] == -1) then return true end //don't do damage if we're GOD!!!!! unless its a pit or other instakill floor of course.
	if t.player.phealth <= 0 then 
		if t.player.playerstate == PST_DEAD then
			return true //end and cancel damage if the player is already dead
		else //zombie player bug, allow attack to go through to prevent immortal players
			P_DamageMobj(t, i, s, d, DMG_INSTAKILL) //instantly kill the player because they're supposed to be dead anyways
		end
	end
	
	local dmgnum = 0 //because of scope aughhhhhhhhhhhh
	
	if i or s then //if inflictor or source exists in
		if (i and i.rfwdamage ~= nil) or (s and s.rfwdamage ~= nil) then //do it this way
			dmgnum = (i and i.rfwdamage) or (s and s.rfwdamage) or 0 //goyim shit
		elseif (i and i.info.rfwdamage ~= nil) or (s and s.info.rfwdamage ~= nil) then //do it this way
			dmgnum = P_RandomRange((i and i.info.rfwdamage or s and s.info.rfwdamage), (i and i.info.rfwmaxdamage or s and s.info.rfwmaxdamage)) or 0 //goyim shit
		else //this is fallback for the globals table
			dmgnum = P_RandomRange(((RFW.DAMAGETABLE[i and i.type or s and s.type]) and RFW.DAMAGETABLE[i and i.type or s and s.type][1] or RFW.DefaultDamage[1]), (((RFW.DAMAGETABLE[i and i.type or s and s.type]) and RFW.DAMAGETABLE[i and i.type or s and s.type][2] or RFW.DefaultDamage[2]))) or 0 //goyim shit
		end
		//ohhh boy... dmgnum = random number range between RFW.DAMAGETABLE[1] at either inflictor's object type or source's object type if inflictor is nil (RFW.DAMAGETABLE[i.type or s.type][1]) ONLY IF a key at i.type or s.type exists ((RFW.DAMAGETABLE[i.type or s.type]) and-)
		//to RFW.DAMAGETABLE[i.type or s.type][2], same restrictions
	elseif RFW.ACIDTABLE[dt] then //if neither inflictor nor source exist and we can find the damagetype in the acid table (terrain damage)
		if RFW.ACIDTABLE[dt] == -1 then //-1 indicates an instakill
			dmgnum = 9999999999999999999999999999
		elseif leveltime % RFW.DMGTIC == 0 then //does this game tic line up with our damage tic???
			dmgnum = RFW.ACIDTABLE[dt] //if so then do damage from the acidtable
		else
			dmgnum = 0 //else don't do damage
		end
	end
/* custom rampage stuff for rails */
	/*if (i and i.valid) then
		if i.flags2 & MF2_RAILRING then
			dmgnum = 150 //unvarying 150 damage
		end
	end*/
/* end custom rampage stuff */
	
	if override == true or (d ~= 1 and d ~= 0) then //if we have a custom damage amount provided through P_DamageMobj
		dmgnum = d //allow manual overriding of damage amount
	end
	
	dmgnum = FixedInt(FixedCeil(FixedDiv($*FU, t.player.health_defense)))
	
	if dmgnum ~= 0 then //might as well not run this if we do no damage
		if s and s.type == MT_PLAYER then
			S_StartSound(s, sfx_hitsnd, s.player)
		end
		if dmgnum >= 5 then
			GLFlash(t.player, 35, 2)
			RFW.Bleed(t)
		end
		local armordmg
		local healthdmg
		if t.player.parmor then
			armordmg = (dmgnum * t.player.papval)/100
			healthdmg = dmgnum - armordmg
			t.player.parmor = $ - armordmg //subtract a percentage of dmgnum equal to the armor's protection value from our armor points we'll let it flow into negatives if needed for later calculations
		else
			healthdmg = dmgnum
		end
		t.player.phealth = $ - healthdmg //subtract current value by dmgnum, if we have armor make sure its only to the remaining percentage
		if t.player.parmor < 0 then //if we have negative armor from earlier...
			t.player.phealth = $ + t.player.parmor //also subtract that armor debt from our health, we add here since this should always be a negative number.
			t.player.parmor = 0 //set parmor to 0 since we've "paid our crippling armor debt now"
		end
		if i or s and not (nkb == true) then
			P_Thrust(t, i and i.angle or s and s.angle, (dmgnum * t.scale/3)) //if this isnt sector damage then do knockback
			//knockback to target at the angle of either inflictor or source, at one third of our damage number in fracunits
			//(multiplied by t.scale instead of FU for proper knockback at player scaling, this can be changed to i.scale or s.scale if you want wacky knockback based on projectile size instead of target size
		end
	end
	if t.player.parmor < 0 then //another check if we somehow still have negative armor
		print("guh, fucking idiot broke the mod and has negative armor, fixing now")
		t.player.parmor = 0 //you know, just incase
	end
	if t.player.phealth <= 0 then //if we don't have any health left
		P_DamageMobj(t, i, s, d, DMG_INSTAKILL) //KILL THE PLAYER, replace this with custom death function at some point
		return true
	end
	return true
end)

addHook("MobjDamage", Playerdamage, MT_PLAYER) //add a hook with our function, normally this would be inline but Playerdamage would maybe be an actually somewhat useful function

rawset(_G, "Playerheal", function(player, armor, amount, cap, protvalue)
	if armor == false or armor == 0 then //we're healing health, not armor
		if player.phealth >= cap and cap ~= 0 then return true //override collision for touchspecial hook, don't pick up item
		elseif player.phealth + amount > cap and cap ~= 0 then //check if uhhh uhmmm uhhhhhhhh i forgot lol
		//check if we'll exceed the health cap by healing off this
			local newhealth = max(0, min((cap - player.phealth), amount)) //new healing value so we can reach the cap, we avoid setting the health directly as safety
			player.phealth = min($ + newhealth, RFW.OHealth)
		else
			player.phealth = min($ + amount, RFW.OHealth)
		end
	else //we're healing armor, not health
		if player.parmor >= cap and cap ~= 0 and player.papval >= protvalue then return true
		elseif player.parmor + amount > cap and cap ~= 0 then
			local newarmor = max(0, min((cap - player.parmor), amount))
			player.parmor = min($ + newarmor, RFW.MArmor)
		else
			player.parmor = min($ + amount, RFW.MArmor)
		end
		if protvalue ~= 0 then
			player.papval = protvalue
		end
	end
	return false
end)

addHook("TouchSpecial", function(s, t) //make this an inline and embedded function so we can run some checks first
	if not (s and s.valid) then return end //if the item doesnt exist then stop
	if not RFW.HEALITEMS[s.type] then return end //if theres not a heal table value for the item then stop
	if not (t and t.valid) then return end //if the item's consumer doesnt exist then stop
	local isarmor = RFW.HEALITEMS[s.type][1] or false //default values for stuff
	local healamount = RFW.HEALITEMS[s.type][2] or 25
	local healcap = RFW.HEALITEMS[s.type][3] or 100
	local armorprot = RFW.HEALITEMS[s.type][4] or 0
	return Playerheal(t.player, isarmor, healamount, healcap, armorprot) //run the healing function with our values, return so that the return value from the function decides whether or not we pick up the item
end) 

addHook("MapLoad", function() //dont save health and armor in comp modes
	if not (gametyperules & GTR_CAMPAIGN) then
		for p in players.iterate do
			p.phealth = RFW.MHealth
			p.parmor = 0
			p.papval = 0
			p.powers[pw_shield] = 0
		end
	end
end)